from flask import *
from loguru import logger
import os
import datetime
import base64
import time
import yaml
import subprocess
import traceback
import re

app = Flask(__name__)
logger.add('log.log')

def get_local_ip():
    try:
        ip_address=subprocess.check_output(['hostname','-I']).decode().split(' ')
        if ip_address:
            return ip_address[0]
    except:
        return "无法获取本机局域网IP地址"

local_ip = get_local_ip()
print("本机局域网IP地址: ", local_ip)

clipboard = []
file_list = []
@app.route('/download/<path:filename>')
def download_file(filename):
    data_dir = os.path.join(app.root_path, 'files')
    return send_file(os.path.join(data_dir, filename))

@app.route('/clipboard', methods=['GET', 'POST'])
def handle_clipboard():
    if request.method == 'GET':
        response = '<h1>Clipboard</h1>'
        for item in clipboard[:10]:
            response += f'<p>[{item["time"]}] {item["ip"]}: {item["text"]}</p>'
        return response
    elif request.method == 'POST':
        post_data = request.form['text']
        data={
            'time': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'ip': request.remote_addr,
            'text': post_data
        }
        clipboard.append(data)
        logger.info(json.dumps(data))
        return redirect(url_for('index'))

@app.route('/files', methods=['GET', 'POST'])
def handle_files():
    if request.method == 'GET':
        response = '<h1>File List</h1>'
        for item in file_list[-10:]:
            response += f'<p>[{item["time"]}] {item["ip"]}: {item["filename"]},<a href="{item["filename"]}" download>下载</a></p>'
        return response
    elif request.method == 'POST':
        file_data = request.files['file'].read()
        filename = request.files['file'].filename
        data_dir = os.path.join(app.root_path, 'files')
        with open(os.path.join(data_dir,filename), 'wb') as file:
            file.write(file_data)
        file_list.append({
            'time': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'ip': request.remote_addr,
            'filename': filename
        })
        return redirect(url_for('index'))

@app.route('/getconfig', methods=['GET'])
def generate_clash_config():
    config = request.args.get('config')
    _info = config.split(":")
    ip = _info[0]
    port = _info[1]
    user_name = _info[2]
    pwd = _info[3]
    name = "SOCKS5-%s" % ip
    config = {
        "proxies": [
            {
                "name": name,
                "type": "socks5",
                "server": ip,
                "port": int(port),
                "username": user_name,
                "password": pwd
            }
        ],
        "proxy-groups": [
            {
                "name": "Proxy Group",
                "type": "select",
                "proxies": [
                    name
                ]
            }
        ],
        "rules": [
            "IP-CIDR,0.0.0.0/8,DIRECT",
            "IP-CIDR,10.0.0.0/8,DIRECT",
            "IP-CIDR,127.0.0.0/8,DIRECT",
            "IP-CIDR,169.254.0.0/16,DIRECT",
            "IP-CIDR,172.16.0.0/12,DIRECT",
            "IP-CIDR,192.168.0.0/16,DIRECT",
            "IP-CIDR,224.0.0.0/4,DIRECT",
            "IP-CIDR,240.0.0.0/4,DIRECT",
            "MATCH,*,Proxy Group"
        ]
    }
    config_yaml = yaml.dump(config)
    return config_yaml

@app.route('/generate_clash_config', methods=['GET'])
def handle_generate_clash_config():
    name = request.args.get('config')
    _info = name.split(":")
    ip = _info[0]
    clash_url = f"http://{local_ip}/getconfig?config={name}"
    clipboard.append({
        'time': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
        'ip': request.remote_addr,
        'text': clash_url
    })
    print("Clipboard+++", clash_url)
    return redirect(url_for('index'))

@app.route('/')
def index():
    print (clipboard,'+'*9,clipboard[:10:-1])
    return render_template('index.html', clipboard=clipboard[::-1][:5], files=file_list[::-1][:6],ct=str(time.time()))

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)
